package com.raa.core;

import com.raa.log.LoggerProvider;

import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.logging.Logger;

public class RaABuilder {

	private static Logger logger = LoggerProvider.provide(RaABuilder.class);

	private LinkedList<Role> roles;

	public RaABuilder ( ) {
		logger.info("开始创建 RaA 实例");
		this.roles = new LinkedList<>();
	}

	public RaABuilder role(String name) {
		logger.info("添加新的角色: " + name);
		this.roles.push(new Role(name));
		return this;
	}

	public RaABuilder role(Class<?> clazz) {
		com.raa.annotation.Role role = clazz.getAnnotation(com.raa.annotation.Role.class);
		if (role == null) throw new RuntimeException(String.format("[%s] 没有标记 Role 注解", clazz.getName()));
		this.role(role.name());
		for (Class<? extends Validator> validator : role.validators()) {
			this.addValidator(validator);
		}
		return this;
	}

	public RaABuilder addValidator(Class<? extends Validator> validatorClass) {
		try {
			this.addValidator(validatorClass.getConstructor().newInstance());
			return this;
		} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}

	public RaABuilder addValidator(Validator validator) {
		if (this.roles.isEmpty()) {
			throw new NullPointerException("尚未添加角色");
		} else {
			Role role = this.roles.getFirst();
			role.addValidator(validator);
		}
		return this;
	}

	public RaA build() {
		return build(RaA.GLOBAL_RAA_NAME);
	}

	public RaA build(String name) {
		synchronized ( RaA.instances ) {
			if (RaA.instances.get(name) == null) {
				RaA raA = new RaA(name, this.roles);
				RaA.instances.put(name, raA);
				logger.info("RaA 实例 [" + name + "] 已登记");
				return raA;
			} else {
				throw new RuntimeException("RaA 实例 [" + name + "] 已经登记，请勿重复录入。");
			}

		}
	}
}
